home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / mod2tutr.zip / CHAP05.TXT < prev    next >
Text File  |  1989-01-18  |  24KB  |  527 lines

  1.  
  2.                                                      Chapter 5
  3.  
  4.                                            MODULA-2 PROCEDURES
  5.  
  6.  
  7.  
  8. AN OVERALL PROGRAM OUTLINE
  9. ______________________________________________________________
  10.  
  11. In order to completely define the procedure, we will need to
  12. lay some groundwork in the form of a few definitions.
  13.  
  14. Program Heading - This is the easiest part since it is only
  15.      one line, at least it has been in all of our programs up
  16.      to this point.  It is simply the MODULE line, and it
  17.      doesn't need to be any more involved than it has been up
  18.      to this point except for one small addition which we will
  19.      cover in a later chapter.
  20.  
  21. Declaration Part - This is the part of the Modula-2 source
  22.      code in which all constants, variables, and other user
  23.      defined auxiliary operations are defined.  In some of the
  24.      programs we have examined, there have been one or more
  25.      var declarations and in one case a constant was declared.
  26.      These are the only components of the declaration part we
  27.      have used up to this time.  There are actually four
  28.      components in the declaration part, and the procedures
  29.      make up the fourth part.  We will cover the others in the
  30.      next chapter.
  31.  
  32. Statement Part - This is the last part of any Modula-2
  33.      program, and it is what we have been calling the main
  34.      program.  It always exists bounded by the reserved words
  35.      BEGIN and END just as it has in all of our examples to
  36.      this point.
  37.  
  38. It is very important that you grasp the above definitions
  39. because we will be referring to them constantly during this
  40. chapter, and throughout the remainder of this tutorial.  With
  41. that introduction, let us look at our first Modula-2 program
  42. with a procedure in it.  It will, in fact, have three
  43. procedures.
  44.  
  45.  
  46.  
  47. WHAT IS A PROCEDURE?
  48. ______________________________________________________________
  49.  
  50. A Procedure is a group of statements, either predefined by the
  51. compiler writer, or defined by you, that can be called upon
  52. to do a specific job.  In this chapter we will see how to
  53. write and use a procedure.  During your future programming
  54. efforts, you will use many procedures.  In fact, you have
  55. already used some because the WriteString, WriteLn, etc.
  56. procedures you have been using are predefined procedures.
  57.  
  58.                                                            5-1
  59.  
  60.                                         Chapter 5 - Procedures
  61.  
  62. Examine the program named PROCED1.MOD for      ===============
  63. your first look at a user defined                PROCED1.MOD
  64. procedure.  In this program, we have the       ===============
  65. usual header with one variable defined.
  66. Ignore the header and move down to the main program beginning
  67. with line 26.  We will come back to all of the statements
  68. prior to the main program in a few minutes.
  69.  
  70. The main program is very easy to understand based on all of
  71. your past experience with Modula-2.  First we somehow write
  72. a header (WriteHeader), then write a message out 8 times
  73. (WriteMessage), and finally we write an ending out
  74. (WriteEnding).  Notice that with the long names for the
  75. procedure names, no comments are needed because the program
  76. is self documenting.  The only problem we have is, how does
  77. the computer actually do the three steps we have asked for.
  78. That is the purpose for the 3 procedures defined earlier
  79. starting in lines 8, 14, and 20.  Modula-2 requires that
  80. nothing can be used until it has been defined, so the
  81. procedures are required to be defined prior to the main
  82. program.  This may seem a bit backward to you if you are
  83. experienced in some other languages like FORTRAN, BASIC, or
  84. C, but it will make sense as you gain experience.
  85.  
  86.  
  87. HOW DO WE DEFINE A PROCEDURE?
  88. ______________________________________________________________
  89.  
  90. We will begin with the procedure at line 8.  We must start
  91. with the reserved word PROCEDURE followed by the name we have
  92. chosen for our procedure, in this case WriteHeader which is
  93. required to follow all of the rules for naming an identifier.
  94. The procedure line must be terminated with a semi-colon.
  95. Following the procedure line, we can include more import
  96. lists, define variables, or any of several other things.  We
  97. will go into a complete definition of this part of the program
  98. in the next chapter, just keep in mind that other quantities
  99. can be inserted here.  We finally come to the procedure body
  100. which contains the actual instructions we wish to execute in
  101. the procedure.  In this case, the procedure body is very
  102. simple, containing only a WriteString and a WriteLn
  103. instruction, but it could have been as complex as we needed
  104. to make it.
  105.  
  106. At the end of the procedure, we once again use the reserved
  107. word END followed by the same name as we defined for the
  108. procedure name.  In the case of a procedure, the final name
  109. is followed by a semicolon instead of a period.  Other than
  110. this small change, a procedure definition is identical to that
  111. of the program itself.
  112.  
  113. When the main program comes to the WriteHeader statement in
  114. line 27, it knows that it is not part of its standard list of
  115. executable instructions, so it looks for the user defined
  116.  
  117.                                                            5-2
  118.  
  119.                                         Chapter 5 - Procedures
  120.  
  121. procedure by that name.  When it finds it, it transfers
  122. control of the program sequence to there, and begins executing
  123. those instructions.  When it executes all of the instructions
  124. in the procedure, it finds the end statement of the procedure
  125. and returns to the next statement in the main program.  When
  126. the main program finally runs out of things to do, it arrives
  127. at its own end statement and terminates.
  128.  
  129. As the program executes the for loop, it is required to call
  130. the WriteMessage procedure 8 times, each time writing its
  131. message on the monitor, and finally the main program finds and
  132. executes the WriteEnding procedure.  This should be very
  133. straightforward and should pose no real problem for you to
  134. understand.  When you think you understand what it should do,
  135. compile and run it.
  136.  
  137.  
  138. NOW FOR A PROCEDURE THAT USES SOME DATA
  139. ______________________________________________________________
  140.  
  141. The last program was interesting to show       ===============
  142. you how a procedure works but if you would       PROCED2.MOD
  143. like to see how to get some data from the      ===============
  144. calling program to the procedure, the
  145. program named PROCED2.MOD will illustrate this.  We will once
  146. again go straight to the program starting in line number 25.
  147. We immediately notice that the program is nothing more than
  148. one big for loop which we go through 3 times.  Each time
  149. through the loop we call several procedures, some that are
  150. system defined, and some that are user defined.  This time
  151. instead of the simple procedure name, we have a variable in
  152. the parentheses behind the variable name.  In these
  153. procedures, we will take some data with us to the procedures,
  154. when we call them, just like we have been  doing  with the
  155. WriteString and WriteInt procedures.
  156.  
  157. When we execute the statement in line 28, because of the
  158. variable named Thing defined in the parentheses, we will take
  159. some data to the procedure named PrintDataOut where it will
  160. be printed.  The procedure PrintDataOut starting in line 9
  161. also contains a pair of parentheses with a variable named
  162. Puppy which is of type integer.  This says that it is
  163. expecting a variable to be passed to it from the calling
  164. program and it expects the variable to be of type integer.
  165. Back in the main program, we see on line 28, that the program
  166. did make the call to the procedure with a variable named Thing
  167. which is an integer type variable, so everything is fine.
  168. The procedure prefers to call the variable passed to it Puppy
  169. but that is perfectly acceptable, it is the same variable.
  170. The procedure writes the value of Puppy, which is really the
  171. variable Thing in the main program, in a line with an
  172. identifying string, then changes the value of Puppy before
  173. returning to the main program.
  174.  
  175.                                                            5-3
  176.  
  177.                                         Chapter 5 - Procedures
  178.  
  179. SOME NEW TERMINOLOGY
  180. ______________________________________________________________
  181.  
  182. The parameter in the calling program is referred to as the
  183. actual parameter, and the parameter in the procedure is called
  184. the formal parameter.  In this procedure then, the actual
  185. parameter is named Thing, and Puppy is the formal parameter.
  186. Note that this terminology is not unique to Modula-2, but is
  187. used to define terms in many modern programming languages.
  188.  
  189. Upon returning to the main program, we print out another line
  190. with three separate parts (notice the indenting and the way
  191. it makes the program more readable), then calls the next
  192. procedure PrintAndModify which appears to do the same thing
  193. as the last one.  Indeed, studying the procedure itself leads
  194. you to believe they are the same, except for the fact that
  195. this one prefers to use the name Cat for the formal parameter
  196. name.  There is one subtle difference in this procedure, the
  197. reserved word VAR in the header, line 17.
  198.  
  199.  
  200. VALUE AND VARIABLE PARAMETERS
  201. ______________________________________________________________
  202.  
  203. In the first procedure, the reserved word VAR was omitted.
  204. This is a signal to the compiler that this procedure will not
  205. receive a reference to the actual parameter variable.
  206. Instead, it will receive a local copy of the variable which
  207. it can use in whatever way it needs to.  When it is finished,
  208. however, it can not return any changes in the variable to the
  209. main program because it can only work with its copy of the
  210. variable.  This is therefore a one-way parameter, since it can
  211. only pass data to the procedure.  This is sometimes called a
  212. "call by value" or a "value parameter" in literature about
  213. Modula-2 and a few other modern programming languages.
  214.  
  215. In the second procedure, the reserved word VAR was included.
  216. This signals the compiler that the actual variable in this
  217. procedure is meant to be passed to the procedure, and not just
  218. the value of the variable.  The procedure can use this
  219. variable in any way it desires, and since it has access to the
  220. variable in the main program, it can alter it if it so
  221. desires.  This is therefore a two-way parameter, since it can
  222. pass data from the main program to the procedure and back
  223. again.  This is sometimes called a "call by reference" or a
  224. "variable parameter" in software literature.
  225.  
  226.  
  227.  
  228. WHICH SHOULD BE USED?
  229. ______________________________________________________________
  230.  
  231. It is up to you to decide which of the two parameter passing
  232. schemes you should use for each application.  The "two-way"
  233.  
  234.                                                            5-4
  235.  
  236.                                         Chapter 5 - Procedures
  237.  
  238. scheme, the variable parameter, seems to give the greatest
  239. flexibility, so your first thought is to simply use it
  240. everywhere.  But that is not a good idea because it gives
  241. every procedure the ability to corrupt your main program
  242. variables.  In addition, if you use a value parameter in the
  243. procedure definition, you have the ability to call the
  244. procedure with a constant in that part of the call.  A good
  245. example is given in lines 12, 20, 30, 34, and 38 of the
  246. present program.  If WriteInt were defined with a variable
  247. parameter, we could not use a constant here, but instead would
  248. have to set up a variable, assign it the desired value, then
  249. use the variable name instead of the 5.  In addition, when a
  250. value parameter is used, an expression can be used for the
  251. actual parameter such as "Thing + 12".  This cannot be done
  252. with a variable parameter because it is not possible to return
  253. a value to an expression.
  254.  
  255. There is one other reason to use a variable parameter.  When
  256. a value parameter is used, a copy of the parameter is made and
  257. the copy is passed to the procedure.  If it happens to be a
  258. very large variable, such as a record or an array, (neither
  259. of which we have studied yet), it could be very inefficient
  260. to generate and pass a copy of the entire variable.  You may
  261. choose to make it a variable parameter so that the procedure
  262. can refer back to the original data rather than work with a
  263. local copy.  You must take care that the procedure does not
  264. accidentally corrupt the original data.
  265.  
  266. Finally, if a value parameter is used, the actual parameter
  267. and the formal parameter only need to be assignment
  268. compatible, so a single procedure could be used for either
  269. integer or cardinal type data.
  270.  
  271.  
  272.  
  273. BACK TO THE PROGRAM ON DISPLAY, PROCED2
  274. ______________________________________________________________
  275.  
  276. We have already mentioned that both of the procedures modify
  277. their respective local variables, but due to the difference
  278. in "call by value" in the first, and "call by reference" in
  279. the second, only the second can actually get the modified data
  280. back to the calling program.  This is why they are named the
  281. way they are.  One other thing should be mentioned.  Since it
  282. is not good practice to modify the variable used to control
  283. the for loop, (and downright erroneous in many cases) we make
  284. a copy of it and call it Thing for use in the calls to the
  285. procedures.  Based on all we have said above, you should be
  286. able to figure out what the program will do, then compile and
  287. run it.
  288.  
  289.  
  290.  
  291.  
  292.                                                            5-5
  293.  
  294.                                         Chapter 5 - Procedures
  295.  
  296. SEVERAL PARAMETERS PASSED AT ONCE
  297. ______________________________________________________________
  298.  
  299. Examine the program named PROCED3.MOD for      ===============
  300. an example of a procedure definition with        PROCED3.MOD
  301. more than one variable being passed to it.     ===============
  302. In this case four parameters are passed to
  303. the procedure.  Three of the parameters are one-way and one
  304. is a two-way parameter.  In this case we simply add the three
  305. numbers and return the result to the main program.  Good
  306. programming practice would dictate the placement of the single
  307. "call by reference" by itself and the others grouped together,
  308. but it is more important to demonstrate to you that they can
  309. be in any order you desire.  This is a very straightforward
  310. example that should pose no problem to you.  Compile and run
  311. it.
  312.  
  313.  
  314.  
  315. SCOPE OF VARIABLES
  316. ______________________________________________________________
  317.  
  318. The program named PROCED4.MOD is an            ===============
  319. illustration of scope of variables, or           PROCED4.MOD
  320. where variables can be used in a program.      ===============
  321. The three variables defined in lines 6, 7,
  322. and 8, are of course available in the main program because
  323. they are defined prior to it.  The two variables defined in
  324. the procedure are available within the procedure because that
  325. is where they are defined.  However, because a variable named
  326. Count is defined both places, they are two completely separate
  327. variables.  The main program can never use the variable Count
  328. defined in the procedure, and the procedure can never use the
  329. variable Count defined in the main program.  They are two
  330. completely separate and unique variables with no ties between
  331. them.  This is useful because when your programs grow, you can
  332. define a variable in a procedure, use it in whatever way you
  333. wish, and not have to worry that you are corrupting some other
  334. global variable.  The variables in the main program are called
  335. global variables because they are available everywhere.
  336.  
  337. In addition to the above scope rules, the variable named Apple
  338. in the procedure is not available to the main program.  Since
  339. it is defined in the procedure, it can only be used in the
  340. procedure.  The procedure effectively builds a wall around the
  341. variable Apple and its own Count so that neither is available
  342. outside of the procedure.  We will see in the next chapter
  343. that procedures can be nested leading to further hiding of
  344. variables.  This program is intended to illustrate the scope
  345. of variables, and it would be good for you to study it, then
  346. compile and run it.
  347.  
  348.  
  349.  
  350.                                                            5-6
  351.  
  352.                                         Chapter 5 - Procedures
  353.  
  354. A PROCEDURE CAN CALL ANOTHER PROCEDURE
  355. ______________________________________________________________
  356.  
  357. The program named PROCED5.MOD illustrates      ===============
  358. procedures that call other procedures.           PROCED5.MOD
  359. Study of this program will reveal that         ===============
  360. procedure Three starting on line 19 calls
  361. procedure Two which in turn calls procedure One.  The main
  362. program calls all three, one at a time, and the result is a
  363. succession of calls which should be rather easy for you to
  364. follow.  The general rule is, "any program or procedure can
  365. call any other procedure that has been previously defined, and
  366. is visible to it."  (We will say more about visibility later.)
  367. Study this program then compile and run it.
  368.  
  369.  
  370.  
  371. A FUNCTION PROCEDURE
  372. ______________________________________________________________
  373.  
  374. Examine the program named FUNCTION.MOD for    ================
  375. an example of a function procedure.  This       FUNCTION.MOD
  376. contains a procedure very much like the       ================
  377. ones we have seen so far with one
  378. difference.  In the procedure heading, line 6, there is an
  379. added ":  INTEGER" at the end of the parameter list.  This is
  380. a signal to the system that this procedure is a function
  381. procedure and it therefore returns a value to the calling
  382. program in a way other than that provided for by parameter
  383. references as we have used before.  In fact, this program
  384. returns a single data value that will be of type integer.
  385.  
  386. In line 16 of the calling program, we find the call to the
  387. procedure which looks like the others we have used except that
  388. it is used in an assignment statement as though it is an
  389. integer type variable.  This is exactly what it is and when
  390. the call is completed, the QuadOfSum(Dogs,Cats) will be
  391. replaced by the answer and then assigned to the variable Feet.
  392. The entire call can therefore be used anyplace in a program
  393. where it is legal to use an integer type variable.  This is
  394. therefore a single value return and can be very useful in the
  395. right situation.  A function procedure can only return a
  396. simple unstructured type.  These types are, INTEGER, CARDINAL,
  397. REAL, BOOLEAN, subrange, or enumeration.
  398.  
  399. A relatively recent addition to Modula-2 allows a function
  400. procedure to return any structured type, not only simple
  401. types.  This means that records or arrays can be returned.
  402. This may not be available with your compiler since it is so
  403. new.
  404.  
  405. One additional point must be made here.  If a function
  406. procedure does not require any parameters, the call to it must
  407. include empty parentheses, and the definition of the procedure
  408.  
  409.                                                            5-7
  410.  
  411.                                         Chapter 5 - Procedures
  412.  
  413. must include empty parentheses also.  This is by definition
  414. of the Modula-2 language.
  415.  
  416. In the procedure, we had to do one thing slightly different
  417. in order to get the return value and that was to use the
  418. RETURN reserved word.  Whenever we have completed the desired
  419. calculations or whatever we need to do, we put the result that
  420. is to be returned to the main program in the parentheses
  421. following the return and the procedure will terminate, return
  422. to the calling program, and take the value with it as the
  423. answer.  Due to decision making, we may have several return
  424. statements in the procedure but only one will be exercised
  425. with each call.  It is an error to come to the end statement
  426. of a function procedure since that would constitute a return
  427. without the benefit of the return statement, and no value
  428. would be returned to the calling program.
  429.  
  430.  
  431. WHAT IS RECURSION?
  432. ______________________________________________________________
  433.  
  434. Recursion is simply a procedure calling       ================
  435. itself.  If you have never been introduced      RECURSON.MOD
  436. to recursion before, that definition          ================
  437. sounds too simple but that is exactly what
  438. it is.  You have probably seen a picture containing a picture
  439. of itself.  The picture in the picture also contains a picture
  440. of itself, the end result being an infinity of pictures.
  441. Examine the file named RECURSON.MOD for an example of a
  442. program with recursion.
  443.  
  444. In the main program, Count is set to 7 and the procedure is
  445. called taking along Count as a parameter.  In the procedure,
  446. we display a line containing the value of the variable, now
  447. called Index, and decrement it.  If the variable is greater
  448. than zero, we call the same procedure again, this time
  449. entering it with the value of 6.  It would be reasonably
  450. correct to think of the system as creating another copy of
  451. the procedure for this call.  The variable Index would be
  452. reduced to 5, and another copy of the procedure would be
  453. called.  Finally, the variable would be reduced to zero and
  454. the return path from procedure to procedure would be taken
  455. until the main program would be reached, where the program
  456. would terminate.
  457.  
  458. Rather than making a complete new copy of the procedure for
  459. each recursive call, the same code would be run each time
  460. through and all of the data would be stored away on the
  461. program stack each time through.  You have no need to worry
  462. about this because it is all taken care of for you by the
  463. system.  You simply call the same procedure as though it were
  464. any other procedure and the system will worry about all of the
  465. details except for one.  It is up to you to see that there is
  466. some mechanism by which the process will terminate.  If there
  467.  
  468.                                                            5-8
  469.  
  470.                                         Chapter 5 - Procedures
  471.  
  472. were no decrementing statement in the procedure, this program
  473. would never reach an end and the stack would overflow,
  474. resulting in an error message and termination of the program.
  475. It would be worth your time to remove the decrementing
  476. statement and observe this, after you compile and run it the
  477. way it is now.
  478.  
  479. Recursion can be very useful for those problems that warrant
  480. its use.  This example is a very stupid use of recursion, but
  481. is an excellent method for giving an example of a program with
  482. recursion that is simple and easy to understand.  Further
  483. examples of recursion will be given later in this tutorial.
  484.  
  485.  
  486. DIRECT AND INDIRECT RECURSION
  487. ______________________________________________________________
  488.  
  489. This example uses direct recursion because the procedure calls
  490. itself directly.  It is also possible to use indirect
  491. recursion where procedure A calls B, B calls A, etc.  Either
  492. method is available and useful depending on the particular
  493. circumstances.
  494.  
  495. WHAT IS AN AUTOMATIC VARIABLE?
  496. ______________________________________________________________
  497.  
  498. They are not actually called automatic variables.  The term
  499. is borrowed from the C programming language, but they act the
  500. same.  When a procedure is called, its local variables do not
  501. exist.  They are generated, stored on a stack, used during the
  502. lifetime of the procedure, and disposed of when control is
  503. given back to the calling program.  The formal parameters are
  504. also handled in the same way.  The variables named Count and
  505. Apple in lines 11 and 12 of PROCED4.MOD are automatic, and so
  506. is Index in RECURSON.MOD.  The way these variables are handled
  507. is the reason recursion works.  More will be said about this
  508. in chapter 13 of this tutorial.
  509.  
  510. PROGRAMMING EXERCISES
  511. ______________________________________________________________
  512.  
  513. 1.   Write a program to write your name, address, and phone
  514.      number on the monitor with each line in a different
  515.      procedure.
  516.  
  517. 2.   Add a statement to the procedure in RECURSON.MOD to
  518.      display the value of Index after the call to itself so
  519.      you can see the value increasing as the recurring calls
  520.      are returned to the next higher level.
  521.  
  522. 3.   Rewrite TEMPCONV.MOD from chapter 4 putting the
  523.      centigrade to fahrenheit formula in a function procedure.
  524.  
  525.                                                            5-9
  526.  
  527.